package com.dingreading.cloud.admin.controller;

import com.alibaba.fastjson.JSONArray;
import com.dingreading.cloud.admin.entity.StoreMenu;
import com.dingreading.cloud.admin.service.StoreMenuService;
import com.dingreading.cloud.admin.service.StoreRoleMenuService;
import com.dingreading.cloud.admin.util.TreeJsonUtil;
import com.dingreading.cloud.admin.util.redis.RedisService;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.DescribeException;
import com.dingreading.cloud.common.util.RedisParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/system/storeMenu")
@Api(tags = "总部-门店菜单管理")
public class StoreMenuController {

    @Resource
    private StoreMenuService menusService;
    @Resource
    private StoreRoleMenuService roleMenuService;

    @Resource
    private RedisService redisService;


    @ApiOperation(value = "菜单列表")
    @PostMapping(value = "/treeList", produces = "application/json; charset=UTF-8")
    public R<Object> treeList(
            @ApiParam(value = "员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "主菜单id") @RequestParam(value = "id", required = false) Long id
    ) {
        List<StoreMenu> list = null;
        JSONArray treeJson = new JSONArray();
        if (id != null && id > 0) {
            StoreMenu data = menusService.getById(id);
            if (data == null) return R.fail("菜单获取失败");

            list = this.menusService.getByNodesNotId(data.getNodes(), null);
        } else {
            list = this.menusService.getAllList();
        }
        if (CollectionUtils.isNotEmpty(list)) {
            treeJson = TreeJsonUtil.createStoreMenuTreeJson(list);
        }
        return R.ok(treeJson);
    }


    @ApiOperation(value = "根据ID获取信息")
    @PostMapping(value = "/getBean", produces = "application/json; charset=UTF-8")
    public R<Object> getBean(
            @ApiParam(value = "菜单id") @RequestParam Long id,
            @ApiParam(value = "员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "headStaffName") String headStaffName
    ) {
        StoreMenu menu = this.menusService.getById(id);
        return R.ok(menu);
    }

    @Transactional(rollbackFor = DescribeException.class)
    @ApiOperation(value = "添加/修改主菜单")
    @PostMapping(value = "/newBean", produces = "application/json; charset=UTF-8")
    public R<Object> newBean(
            @ApiParam(value = "员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "菜单id") @RequestParam(value = "id", required = false) Long id,
            @ApiParam(value = "标题") @RequestParam(value = "title") String title,
            @ApiParam(value = "路由名") @RequestParam(value = "name", required = false) String name,
            @ApiParam(value = "路径地址path") @RequestParam(value = "path", required = false) String path,
            @ApiParam(value = "图标") @RequestParam(value = "icon", required = false) String icon,
            @ApiParam(value = "标识符") @RequestParam(value = "component", required = false) String component,
            @ApiParam(value = "是否菜单展示") @RequestParam(value = "isMenu", required = false) Boolean isMenu,
            @ApiParam(value = "是否为父菜单") @RequestParam(value = "isParentMenu", required = false) Boolean isParentMenu,
            @ApiParam(value = "运营类型") @RequestParam(value = "operationType") String operationType,
            @ApiParam(value = "合作类型") @RequestParam(value = "cooperationType") String cooperationType
    ) {
        StoreMenu data = null;
        if (id == null || id <= 0) {
            // 获取最大的序号
            int maxOrderNum = menusService.getMaxShowOrder(0L) + 1;

            data = new StoreMenu();
            data.setParentId(0L);
            data.setOrderNum(maxOrderNum);
            data.setEnabled(1);
            data.setAddStaffUid(headStaffUid);
            data.setAddStaffName(headStaffName);
        } else {
            data = menusService.getById(id);
            if (data == null) return R.fail("菜单获取失败");
        }
        data.setName(name);
        data.setPath(path);
        data.setIcon(icon);
        data.setComponent(component);
        data.setTitle(title);
        data.setIsMenu(isMenu);
        data.setIsParentMenu(isParentMenu);
        data.setOperationType(operationType);
        data.setCooperationType(cooperationType);
        data.setLastStaffUid(headStaffUid);
        data.setLastStaffName(headStaffName);
        menusService.saveOrUpdate(data);

        // 更新节点
        if (StringUtils.isBlank(data.getNodes()))
            menusService.updateNodes(data.getId(), String.valueOf(data.getId()).concat("."));

        redisService.setNullLike(RedisParam.STORE_MENU);
        return R.ok();
    }


    @ApiOperation(value = "添加/修改子菜单")
    @PostMapping(value = "/newChildBean", produces = "application/json; charset=UTF-8")
    public R<Object> newChildBean(
            @ApiParam(value = "员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "菜单id") @RequestParam(value = "id", required = false) Long id,
            @ApiParam(value = "标题") @RequestParam(value = "title") String title,
            @ApiParam(value = "上级菜单ID") @RequestParam(value = "parentId") Long parentId,
            @ApiParam(value = "路由名") @RequestParam(value = "name", required = false) String name,
            @ApiParam(value = "路径地址path") @RequestParam(value = "path", required = false) String path,
            @ApiParam(value = "图标") @RequestParam(value = "icon", required = false) String icon,
            @ApiParam(value = "标识符") @RequestParam(value = "component", required = false) String component,
            @ApiParam(value = "是否菜单展示") @RequestParam(value = "isMenu", required = false) Boolean isMenu,
            @ApiParam(value = "是否为父菜单") @RequestParam(value = "isParentMenu", required = false) Boolean isParentMenu,
            @ApiParam(value = "运营类型") @RequestParam(value = "operationType") String operationType,
            @ApiParam(value = "合作类型") @RequestParam(value = "cooperationType") String cooperationType
    ) {
        StoreMenu data = null;
        StoreMenu parentMenus = null;
        if (id == null || id <= 0) {
            // 获取最大的序号
            int maxOrderNum = menusService.getMaxShowOrder(parentId) + 1;

            parentMenus = menusService.getById(parentId);
            if (parentMenus == null) return R.fail("上级菜单获取失败");

            data = new StoreMenu();
            data.setParentId(parentId);
            data.setOrderNum(maxOrderNum);
            data.setEnabled(1);
            data.setAddStaffUid(headStaffUid);
            data.setAddStaffName(headStaffName);
        } else {
            data = menusService.getById(id);
            if (data == null)
                return R.fail("菜单获取失败");
        }
        data.setName(name);
        data.setPath(path);
        data.setIcon(icon);
        data.setComponent(component);
        data.setTitle(title);
        data.setIsMenu(isMenu);
        data.setIsParentMenu(isParentMenu);
        data.setOperationType(operationType);
        data.setCooperationType(cooperationType);
        data.setLastStaffUid(headStaffUid);
        data.setLastStaffName(headStaffName);
        menusService.saveOrUpdate(data);

        // 更新节点
        if (null != parentMenus && StringUtils.isBlank(data.getNodes()))
            menusService.updateNodes(data.getId(), parentMenus.getNodes().concat(String.valueOf(data.getId())).concat("."));

        redisService.setNullLike(RedisParam.STORE_MENU);
        return R.ok();
    }


    @ApiOperation(value = "删除菜单")
    @PostMapping(value = "/dropBean", produces = "application/json; charset=UTF-8")
    public R<Object> dropBean(
            @ApiParam(value = "员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "菜单id") @RequestParam(value = "id") Long id
    ) {
        StoreMenu data = menusService.getById(id);
        if (data == null) return R.fail("菜单获取失败");

        List<StoreMenu> list = menusService.getByNodesNotId(data.getNodes(), id);
        if (CollectionUtils.isNotEmpty(list)) return R.fail("有子菜单不能删除");

        long l = menusService.dropBean(id);
        if (l <= 0) return R.fail("删除失败");
        roleMenuService.dropByMenuId(id);

        redisService.setNullLike(RedisParam.STORE_MENU);
        return R.ok();
    }


    @ApiOperation(value = "上移/下移")
    @PostMapping(value = "/upOrDown", produces = "application/json; charset=UTF-8")
    public R<Object> upOrDown(
            @ApiParam(value = "员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "类型 1.上移 2.下移") @RequestParam(value = "type") Integer type
    ) {
        StoreMenu data = menusService.getById(id);
        if (data == null) return R.fail("获取失败");

        if (type.equals(1)) {
            // 上移
            StoreMenu preData = menusService.getLtOrderNum(data.getParentId(), data.getOrderNum());
            if (preData == null) return R.fail("已在最前");
            // 和前一条记录的序号互换
            Integer prevOrderNum = preData.getOrderNum();
            Integer curOrderNum = data.getOrderNum();
            // 序号互换
            menusService.updateOrderNum(preData.getId(), curOrderNum, headStaffUid, headStaffName);
            menusService.updateOrderNum(data.getId(), prevOrderNum, headStaffUid, headStaffName);
        } else if (type.equals(2)) {
            // 下移
            StoreMenu nextData = menusService.getGtOrderNum(data.getParentId(), data.getOrderNum());
            if (nextData == null) return R.fail("已在最后");
            // 和后一条记录的序号互换
            Integer nextOrderNum = nextData.getOrderNum();
            Integer curOrderNum = data.getOrderNum();
            // 序号互换
            menusService.updateOrderNum(nextData.getId(), curOrderNum, headStaffUid, headStaffName);
            menusService.updateOrderNum(data.getId(), nextOrderNum, headStaffUid, headStaffName);
        } else {
            return R.fail("类型错误");
        }
        redisService.setNullLike(RedisParam.STORE_MENU);
        return R.ok();
    }

    @ApiOperation(value = "更新启用状态")
    @PostMapping(value = "/updateEnabled", produces = "application/json; charset=UTF-8")
    public R<Object> updateEnabled(
            @ApiParam(value = "员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "是否禁用 1.启用 0.禁用") @RequestParam(value = "enabled") Integer enabled
    ) {
        StoreMenu data = menusService.getById(id);
        if (data == null) return R.fail("获取失败");

        boolean b = menusService.updateEnabled(id, enabled, headStaffUid, headStaffName);
        if (!b) return R.fail("操作失败");

        menusService.updateChildEnabled(data.getNodes(), enabled, headStaffUid, headStaffName);
        return R.ok();
    }

}
